iT邦幫忙

2023 iThome 鐵人賽

DAY 29
0
Vue.js

Nuxt 3 初學者指南:30天從基礎到實踐系列 第 29

Day 29 – 實作一個部落格

  • 分享至 

  • xImage
  •  

連續兩天介紹了 Nuxt Content 的用法,今天就試著用 Nuxt Content 和前幾天介紹過的 UnoCSS、Nuxt Image 來實際建立一個簡單的部落格吧!

建立步驟

先準備一張 logo.png 放到 public/

nuxt-project
 ┣ public
 ┃  ┗ logo.png

Step 1

content/ 建立 character/ 資料夾,並建立格式為 .md 的內文檔案。

nuxt-project
 ┣ content
 ┃  ┣ character
 ┃  ┃  ┣ anya.md
 ┃  ┃  ┣ bomd.md
 ┃  ┃  ┣ loid.md
 ┃  ┃  ┗ yor.md

文件內容擷取自維基百科,下方為 anya.md 的程式碼,另外三個檔案結構相同。

// content/character/anya.md
# 〈實驗體007〉安妮亞·佛傑

佛傑一家的最小成員,能對他人進行讀心的超能力少女。為了進入伊甸學園就讀而謊稱是6歲,但實際年齡應為4、5歲左右。特徵為粉髮綠眼、與同學相比較為矮小的身材及頭上奇特的小巫師帽髮飾(可戴兩頂迷你帽)。喜歡花生。因年幼而口語表達不佳,也常誤會他人話語意思。

原是某組織代號「007」[a]的實驗體,因為無法忍受組織不斷強迫自己學習以及沒有童年的生活而逃離研究所,自此使用「安妮亞」的假名並隱瞞自己的能力,輾轉於多個收養家庭與孤兒院之間。在透過讀心發現洛伊德需要一個孩子好執行自己的任務時,因為對間諜感到有趣而成為他的養女,洛伊德對外(包括對約兒)的說法是洛伊德與兩年前亡故的前妻之間所生的女兒。

Step 2

pages/ 建立 character/ 資料夾,再建立 [...slug].vue 檔案。此時路由如果為 /character/[name] 則會顯示路徑為 content/character/[name] 的檔案,如 content/character/anya

nuxt-project
 ┣ pages
 ┃  ┣ character
 ┃  ┃  ┗ [...slug].vue

Step 3

pages/character/[...slug].vue 加入下方程式碼。

// pages/character/[...slug].vue
<template>
  <main class="grid grid-cols-12">
    <nav class="col-span-2">
      <ContentNavigation v-slot="{navigation}" :query="queryContent('character')">
        <ul class="list-none">
          <li v-for="link of navigation[0].children" :key="link._path">
            <NuxtLink :to="link._path" class="no-underline text-blue-500 leading-relaxed font-extrabold hover:underline">
              {{ link.title }}
            </NuxtLink>
          </li>
        </ul>
      </ContentNavigation>
    </nav>
    <ContentDoc>
      <template #default="{ doc }">
        <div class="col-span-6 shadow-md border-solid rounded-xl border-bluegray px-5 pb-5 w-10/12-md m-auto font-mono tracking-widest">
          <ContentRenderer :value="doc" :components="components" />
          <NuxtImg src="logo.png" class="opacity-50 float-right" />
        </div>
      </template>
    </ContentDoc>
  </main>
</template>

<script setup lang="ts">
const components = {
  h1: 'CustomTitle',
  p: 'CustomParagraph'
}
</script>

語法解釋

<ContentNavigation>

此元件在 Day 28 – Nuxt Content Components 文章中有簡單介紹過。
值得注意的是這邊的範例有用到 :query="queryContent('character')",表示使用 query 屬性查詢 <ContentNavigation/> 要使用的內容,且查詢條件為_path: /^\/character/

<ContentRenderer>

此處使用 components 屬性來指定 Markdown 內容渲染成 Html 時要替換成什麼元件。

此處使用 <CustomTitle /> 替換 <h1> 的內容,CustomParagraph 替換 <p> 的內容。
⚠️ 注意:須將要使用的元件放置在 component/content/ 才會自動被引入,否則須手動 import 元件且 'CustomTitle' 須改成 import 的變數,也可以在 nuxt.config.ts 指定目錄下元件為全域

// component/content/CustomTitle.vue
<template>
  <div>
    <h1 class="bg-blue-500 w-fit rounded-xl px-5 py-2 text-white -ml-10">
      <slot />
    </h1>
  </div>
</template>
// component/content/CustomParagraph.vue
<template>
  <div class="text-gray-500">
    <slot />
  </div>
</template>

Step 4

結果如下圖。

透過 Nuxt Content 就可以簡單建立一個 CMS,我們使用 <ContentNavigation> 來產生目錄連結到各篇文章,用 <ContentDoc><ContentRenderer> 來產生內文,像上面範例所示,短短幾行程式碼就可以產生一個部落格,我們不需要設定路由,也不需要寫一堆程式碼來產生頁面,只要專注在所要呈現的內容就好,是不是非常方便呢?

🌞 Upcoming

明天是鐵人賽最後一天啦!明天會介紹如何編譯和佈署開發完的網站,讓網站成功上線。


上一篇
Day 28 – Nuxt Content Components
下一篇
Day 30 – Nuxt 3 Deployment
系列文
Nuxt 3 初學者指南:30天從基礎到實踐30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言